package com.alinesno.cloud.initializr.starter.gateway.rest.gen;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alinesno.cloud.common.facade.response.AjaxResult;
import com.alinesno.cloud.initializr.starter.codegen.entity.GenTable;
import com.alinesno.cloud.initializr.starter.codegen.entity.GenTableColumn;
import com.alinesno.cloud.initializr.starter.codegen.service.IGenTableColumnService;
import com.alinesno.cloud.initializr.starter.codegen.service.IGenTableService;
import com.alinesno.cloud.initializr.starter.dto.GenInfoDto;
import com.alinesno.cloud.initializr.starter.entity.InitializrDbListEntity;
import com.alinesno.cloud.initializr.starter.service.IInitializrDbListService;
import com.alinesno.cloud.initializr.starter.service.IStaticService;
import com.alinesno.cloud.rest.gateway.adapter.page.TableDataInfo;
import com.alinesno.cloud.rest.gateway.adapter.plugins.TranslateCode;
import com.alinesno.cloud.rest.gateway.adapter.security.CurrentAccountJwt;
import com.alinesno.cloud.rest.gateway.adapter.utils.Convert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;


/**
 * 代码生成 操作处理
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("com/alinesno/cloud/initializr/codeGenertor/gen/")
public class GenRest extends GenBaseRest {

    private static final String BLANK_TABLE = "0";

    @Autowired
    private IGenTableService genTableService;

    @Autowired
    private IGenTableColumnService genTableColumnService;

    @Autowired
    private IInitializrDbListService dbListService;

    @Autowired
    private IStaticService staticService ; 
    
    /**
     * 查询代码生成列表
     *
     * @return
     */
    @TranslateCode(plugin = "genControllerCodeGenPlugin")
    @GetMapping("/list")
    public TableDataInfo genList(GenTable genTable) {
        String tableName = genTable.getTableSchema();
        if (BLANK_TABLE.equals(tableName)) {
            genTable.setTableSchema("");
        }
       
        // 处理租户的数据库问题
        List<InitializrDbListEntity> dbList = dbListService.list(
        		new QueryWrapper<InitializrDbListEntity>()
        		.eq("operator_id", CurrentAccountJwt.getUserId())) ; 
        
        List<String> tables = new ArrayList<String>() ; 
        
        for(InitializrDbListEntity db : dbList) {
        	tables.add(db.getDbName()) ;
        }
        
        genTable.setSchemaList(tables); 
        
        startPage();
        
        List<GenTable> list = genTableService.selectGenTableList(genTable);
        return getDataTable(list);
    }

    /**
     * 通过数据库生成代码
     */
    @GetMapping("/genCodeByDb")
    public void genCodeByDb(@RequestParam String id, GenInfoDto genInfo, HttpServletResponse response) throws IOException {
        InitializrDbListEntity dbListEntity = dbListService.findById(id);
        if (dbListEntity != null) {
            BeanUtils.copyProperties(genInfo, dbListEntity);
            dbListService.update(dbListEntity);
            List<GenTable> genTables = genTableService.selectTablesByDbName(dbListEntity.getDbName());
            String[] tables = genTables.stream().map(GenTable::getTableName).toArray(String[]::new);
            byte[] data = genTableService.downloadCode(tables, dbListEntity.getDbName(), genInfo);
           
            // 数据库生成统计+1
            staticService.addGenDatabaseCount();  
            
            genCode(response, data, dbListEntity.getDbName(), null);
        }
    }

    /**
     * 修改代码生成业务
     */
    @GetMapping(value = "/{talbleId}")
    public AjaxResult getInfo(@PathVariable Long talbleId , String dbName) {
        GenTable table = genTableService.selectGenTableById(talbleId);
        
        List<String> tableStr = new ArrayList<String>() ; 
		tableStr.add(dbName) ;
		
        List<GenTable> tables = genTableService.selectGenTableAll(tableStr);
        
        List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(talbleId);
        Map<String, Object> map = new HashMap<String, Object>();
        
        map.put("info", table);
        map.put("rows", list);
        map.put("tables", tables);
        
        return AjaxResult.success(map);
    }

    /**
     * 查询数据库列表
     */
    @GetMapping("/db/list")
    public TableDataInfo dataList(GenTable genTable) {
        startPage();
        List<GenTable> list = genTableService.selectDbTableList(genTable);
        return getDataTable(list);
    }

    /**
     * 查询数据表字段列表
     */
    @GetMapping(value = "/column/{talbleId}")
    public TableDataInfo columnList(Long tableId) {
        TableDataInfo dataInfo = new TableDataInfo();
        List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(tableId);
        dataInfo.setRows(list);
        dataInfo.setTotal(list.size());
        return dataInfo;
    }

    /**
     * 导入表结构（保存）
     */
    @PostMapping("/importTable")
    public AjaxResult importTableSave(String tables) {
        String[] tableNames = Convert.toStrArray(tables);
        // 查询表信息
        List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames);
        genTableService.importGenTable(tableList);
        return AjaxResult.success();
    }

    /**
     * 修改保存代码生成业务
     */
    @PutMapping
    public AjaxResult editSave(@Validated @RequestBody GenTable genTable) {
        genTableService.validateEdit(genTable);
        genTableService.updateGenTable(genTable);
        return AjaxResult.success();
    }

    /**
     * 删除代码生成
     */
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        genTableService.deleteGenTableByIds(ids);
        return AjaxResult.success();
    }

    /**
     * 预览代码
     */
    @GetMapping("/preview/{tableId}")
    public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException {
        Map<String, String> dataMap = genTableService.previewCode(tableId);
        return AjaxResult.success(dataMap);
    }

    /**
     * 生成代码（下载方式）
     */
    @GetMapping("/download/{tableName}")
    public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException {
        byte[] data = genTableService.downloadCode(tableName);
        genCode(response, data, null, null);
    }

    /**
     * 生成代码（自定义路径）
     */
    @GetMapping("/genCode/{tableName}")
    public AjaxResult genCode(@PathVariable("tableName") String tableName) {
        genTableService.generatorCode(tableName);
        return AjaxResult.success();
    }

    /**
     * 同步数据库
     */
    @GetMapping("/synchDb/{tableName}")
    public AjaxResult synchDb(@PathVariable("tableName") String tableName) {
        genTableService.synchDb(tableName);
        return AjaxResult.success();
    }

    /**
     * 批量生成代码
     */
    @GetMapping("/batchGenCode")
    public void batchGenCode(HttpServletResponse response, String tables) throws IOException {
        String[] tableNames = Convert.toStrArray(tables);
        byte[] data = genTableService.downloadCode(tableNames);
        genCode(response, data, null, null);
    }

    /**
     * 生成代码（下载方式）
     */
    @GetMapping("/download/{tableSchema}/{tableName}")
    public void download(HttpServletResponse response, @PathVariable("tableName") String tableName,
                         @PathVariable("tableSchema") String tableSchema) throws IOException {
        byte[] data = genTableService.downloadCode(tableName, tableSchema);
        genCode(response, data, tableSchema, tableName);
    }

}